package com.ruoyi.tzai.service.ai.impl;

import org.springframework.stereotype.Service;
import com.ruoyi.tzai.service.ai.IAIService;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * OpenAI GPT服务实现
 * 
 * @author tzai
 * @date 2025-10-27
 */
@Service("openAIService")
public class OpenAIServiceImpl implements IAIService 
{
    private static final Logger log = LoggerFactory.getLogger(OpenAIServiceImpl.class);
    
    private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json; charset=utf-8");
    
    private String apiKey;
    private String apiEndpoint = "https://api.openai.com/v1/chat/completions";
    private String model = "gpt-4";
    
    private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .build();

    /**
     * 调用OpenAI API
     */
    private String callOpenAI(String prompt, String systemMessage) {
        try {
            JSONObject requestBody = new JSONObject();
            requestBody.put("model", model);
            requestBody.put("messages", new Object[]{
                new JSONObject().fluentPut("role", "system").fluentPut("content", systemMessage),
                new JSONObject().fluentPut("role", "user").fluentPut("content", prompt)
            });
            requestBody.put("temperature", 0.7);
            requestBody.put("max_tokens", 2000);

            Request request = new Request.Builder()
                    .url(apiEndpoint)
                    .addHeader("Authorization", "Bearer " + apiKey)
                    .addHeader("Content-Type", "application/json")
                    .post(RequestBody.create(requestBody.toString(), JSON_MEDIA_TYPE))
                    .build();

            try (Response response = httpClient.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    log.error("OpenAI API调用失败: {}", response.code());
                    return null;
                }

                String responseBody = response.body().string();
                JSONObject jsonResponse = JSON.parseObject(responseBody);
                return jsonResponse.getJSONArray("choices")
                        .getJSONObject(0)
                        .getJSONObject("message")
                        .getString("content");
            }
        } catch (IOException e) {
            log.error("OpenAI API调用异常", e);
            return null;
        }
    }

    @Override
    public String generateSummary(String content, String language) {
        log.info("生成摘要 - 语言: {}, 内容长度: {}", language, content.length());
        
        // 如果没有配置API Key，使用模拟数据
        if (apiKey == null || apiKey.isEmpty()) {
            log.warn("未配置API Key，使用模拟摘要");
            try {
                Thread.sleep(500); // 模拟API延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            if ("en".equals(language)) {
                return "This is an AI-generated summary about " + 
                       (content.length() > 30 ? content.substring(0, 30) + "..." : content) + 
                       ". The content has been intelligently analyzed and key points extracted.";
            } else {
                return "这是一篇关于「" + 
                       (content.length() > 15 ? content.substring(0, 15) + "..." : content) + 
                       "」的资讯摘要。AI已智能分析并提取核心内容。";
            }
        }
        
        String systemMessage = language.equals("en") 
            ? "You are a professional news summarizer. Generate a concise summary of the given article."
            : "你是一个专业的新闻摘要生成器。请为给定的文章生成简洁的摘要。";
        
        String prompt = language.equals("en")
            ? "Please summarize the following article in 2-3 sentences:\n\n" + content
            : "请用2-3句话总结以下文章:\n\n" + content;
        
        return callOpenAI(prompt, systemMessage);
    }

    @Override
    public String translate(String content, String fromLang, String toLang) {
        log.info("翻译 - 从 {} 到 {}, 内容长度: {}", fromLang, toLang, content.length());
        
        // 如果没有配置API Key，使用模拟数据
        if (apiKey == null || apiKey.isEmpty()) {
            log.warn("未配置API Key，使用模拟翻译");
            try {
                Thread.sleep(800); // 模拟API延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            if ("en".equals(toLang)) {
                return "[Translated to English] " + content;
            } else {
                return "[已翻译为中文] " + content;
            }
        }
        
        String systemMessage = "You are a professional translator.";
        String langName = toLang.equals("en") ? "English" : "Chinese";
        String prompt = String.format("Translate the following text to %s:\n\n%s", langName, content);
        
        return callOpenAI(prompt, systemMessage);
    }

    @Override
    public String smartSegmentation(String content, String language) {
        log.info("智能断句 - 语言: {}, 内容长度: {}", language, content.length());
        
        // 如果没有配置API Key，使用简单的分句规则
        if (apiKey == null || apiKey.isEmpty()) {
            log.warn("未配置API Key，使用简单断句规则");
            try {
                Thread.sleep(300); // 模拟处理延迟
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            
            // 按句号、问号、感叹号分割
            String[] sentences = content.split("[。.!！?？;；\n]");
            com.alibaba.fastjson2.JSONArray result = new com.alibaba.fastjson2.JSONArray();
            
            for (int i = 0; i < sentences.length; i++) {
                String sentence = sentences[i].trim();
                if (sentence.length() > 0) {
                    com.alibaba.fastjson2.JSONObject sentenceObj = new com.alibaba.fastjson2.JSONObject();
                    sentenceObj.put("index", i + 1);
                    sentenceObj.put("text", sentence);
                    sentenceObj.put("start", 0);
                    sentenceObj.put("end", sentence.length());
                    result.add(sentenceObj);
                }
            }
            
            return result.toJSONString();
        }
        
        String systemMessage = language.equals("en")
            ? "You are a text segmentation expert. Split the text into natural sentences suitable for text-to-speech."
            : "你是文本断句专家。将文本拆分为适合语音合成的自然句子。";
        
        String prompt = language.equals("en")
            ? "Split the following text into sentences, return as JSON array format [\"sentence1\", \"sentence2\", ...]:\n\n" + content
            : "将以下文本拆分为句子，以JSON数组格式返回 [\"句子1\", \"句子2\", ...]:\n\n" + content;
        
        return callOpenAI(prompt, systemMessage);
    }

    @Override
    public boolean testConnection() {
        try {
            String result = callOpenAI("Hello", "You are a helpful assistant.");
            return result != null && !result.isEmpty();
        } catch (Exception e) {
            log.error("OpenAI连接测试失败", e);
            return false;
        }
    }

    @Override
    public String getModelName() {
        return "OpenAI " + model;
    }

    @Override
    public BilingualSummary generateBilingualSummary(String content, String sourceLang) {
        return generateBilingualSummary(content, sourceLang, "summary");
    }

    @Override
    public BilingualSummary generateBilingualSummary(String content, String sourceLang, String processMode) {
        log.info("生成双语（带模式） - 源语言: {}, 模式: {}, 内容长度: {}", sourceLang, processMode, content.length());
        
        if (processMode == null || processMode.isEmpty()) {
            processMode = "summary";
        }
        
        // 全文模式：只翻译 + 基础断句（避免AI任务过重导致超时）
        if ("full".equalsIgnoreCase(processMode)) {
            return generateFullTextBilingual(content, sourceLang);
        }
        
        // 摘要模式：使用AI生成摘要+断句
        BilingualSummary result = new BilingualSummary();
        
        // 如果没有配置API Key，使用降级方案
        if (apiKey == null || apiKey.isEmpty()) {
            log.warn("未配置API Key，使用降级方案");
            return generateBilingualSummaryFallback(content, sourceLang);
        }
        
        try {
            // 使用统一的提示词构建器
            String systemPrompt = ("cn".equals(sourceLang) || "zh".equals(sourceLang))
                ? IAIService.buildChineseSourcePrompt()
                : IAIService.buildEnglishSourcePrompt();
            
            // 调用 OpenAI API
            String response = callOpenAI(content, systemPrompt);
            
            if (response == null || response.isEmpty()) {
                log.error("OpenAI返回为空，使用降级方案");
                return generateBilingualSummaryFallback(content, sourceLang);
            }
            
            // 解析响应
            parseAndFillBilingualResult(response, result, sourceLang);
            
            log.info("双语摘要生成完成 - 中文摘要长度: {}, 英文摘要长度: {}",
                     result.getCnSummary() != null ? result.getCnSummary().length() : 0,
                     result.getEnSummary() != null ? result.getEnSummary().length() : 0);
            
            return result;
            
        } catch (Exception e) {
            log.error("生成双语失败，使用降级方案", e);
            return generateBilingualSummaryFallback(content, sourceLang);
        }
    }

    /**
     * 解析AI响应并填充结果
     */
    private void parseAndFillBilingualResult(String response, BilingualSummary result, String sourceLang) {
        try {
            String cleanResponse = response.trim();

            // 移除可能的markdown代码块标记
            if (cleanResponse.startsWith("```")) {
                int firstNewline = cleanResponse.indexOf('\n');
                if (firstNewline > 0) {
                    cleanResponse = cleanResponse.substring(firstNewline + 1);
                }
            }
            if (cleanResponse.endsWith("```")) {
                cleanResponse = cleanResponse.substring(0, cleanResponse.lastIndexOf("```"));
            }
            cleanResponse = cleanResponse.trim();

            // 提取中文简短摘要
            String cnSummary = extractSection(cleanResponse, "===中文简短摘要===", "===中文详细内容===");
            if (cnSummary == null) {
                cnSummary = extractSection(cleanResponse, "===Chinese Brief Summary===", "===Chinese Detailed Content===");
            }
            result.setCnSummary(cnSummary != null ? cnSummary.trim() : "");

            // 提取中文详细内容
            String cnContent = extractSection(cleanResponse, "===中文详细内容===", "<<<中文句子>>>");
            if (cnContent == null) {
                cnContent = extractSection(cleanResponse, "===Chinese Detailed Content===", "<<<Chinese Sentences>>>");
            }
            result.setCnContent(cnContent != null ? cnContent.trim() : result.getCnSummary());

            // 提取中文句子
            String cnSentencesText = extractSection(cleanResponse, "<<<中文句子>>>", "===英文简短摘要===");
            if (cnSentencesText == null) {
                cnSentencesText = extractSection(cleanResponse, "<<<Chinese Sentences>>>", "===English Brief Summary===");
            }
            com.alibaba.fastjson2.JSONArray cnSentencesArray = parseSentences(cnSentencesText);
            result.setCnSentences(cnSentencesArray.toJSONString());

            // 提取英文简短摘要
            String enSummary = extractSection(cleanResponse, "===英文简短摘要===", "===英文详细内容===");
            if (enSummary == null) {
                enSummary = extractSection(cleanResponse, "===English Brief Summary===", "===English Detailed Content===");
            }
            result.setEnSummary(enSummary != null ? enSummary.trim() : "");

            // 提取英文详细内容
            String enContent = extractSection(cleanResponse, "===英文详细内容===", "<<<英文句子>>>");
            if (enContent == null) {
                enContent = extractSection(cleanResponse, "===English Detailed Content===", "<<<English Sentences>>>");
            }
            result.setEnContent(enContent != null ? enContent.trim() : result.getEnSummary());

            // 提取英文句子
            String enSentencesText = extractSectionToEnd(cleanResponse, "<<<英文句子>>>");
            if (enSentencesText == null) {
                enSentencesText = extractSectionToEnd(cleanResponse, "<<<English Sentences>>>");
            }
            com.alibaba.fastjson2.JSONArray enSentencesArray = parseSentences(enSentencesText);
            result.setEnSentences(enSentencesArray.toJSONString());

            log.info("成功解析AI响应：中文摘要{}字，详细内容{}字，{}句 | 英文摘要{}字，详细内容{}字，{}句",
                     result.getCnSummary().length(), result.getCnContent().length(), cnSentencesArray.size(),
                     result.getEnSummary().length(), result.getEnContent().length(), enSentencesArray.size());

        } catch (Exception e) {
            log.error("解析AI响应失败: {}", e.getMessage(), e);
            throw new RuntimeException("解析AI响应失败", e);
        }
    }

    /**
     * 从文本中提取指定区间的内容
     */
    private String extractSection(String text, String startMarker, String endMarker) {
        int startIdx = text.indexOf(startMarker);
        if (startIdx < 0) {
            return null;
        }
        startIdx += startMarker.length();

        int endIdx = text.indexOf(endMarker, startIdx);
        if (endIdx < 0) {
            return null;
        }

        return text.substring(startIdx, endIdx).trim();
    }

    /**
     * 从文本中提取从起始标记到末尾的内容
     */
    private String extractSectionToEnd(String text, String startMarker) {
        int startIdx = text.indexOf(startMarker);
        if (startIdx < 0) {
            return null;
        }
        startIdx += startMarker.length();

        return text.substring(startIdx).trim();
    }

    /**
     * 解析句子列表（[S0]sentence\n[S1]sentence\n...）
     */
    private com.alibaba.fastjson2.JSONArray parseSentences(String sentencesText) {
        com.alibaba.fastjson2.JSONArray array = new com.alibaba.fastjson2.JSONArray();

        if (sentencesText == null || sentencesText.trim().isEmpty()) {
            return array;
        }

        String[] lines = sentencesText.split("\n");
        for (String line : lines) {
            line = line.trim();
            if (line.isEmpty()) {
                continue;
            }

            // 查找 [S数字] 标记
            if (line.startsWith("[S")) {
                int closeBracket = line.indexOf(']');
                if (closeBracket > 0) {
                    try {
                        int index = Integer.parseInt(line.substring(2, closeBracket));
                        String text = line.substring(closeBracket + 1).trim();

                        com.alibaba.fastjson2.JSONObject sentenceObj = new com.alibaba.fastjson2.JSONObject();
                        sentenceObj.put("index", index);
                        sentenceObj.put("text", text);
                        array.add(sentenceObj);
                    } catch (NumberFormatException e) {
                        log.warn("跳过无效的句子标记: {}", line);
                    }
                }
            }
        }

        return array;
    }

    /**
     * 全文模式处理：只翻译 + 基础断句
     */
    private BilingualSummary generateFullTextBilingual(String content, String sourceLang) {
        log.info("全文模式处理 - 只翻译+基础断句");
        
        BilingualSummary result = new BilingualSummary();
        
        try {
            if ("cn".equals(sourceLang) || "zh".equals(sourceLang)) {
                // 中文为源语言
                log.info("中文源文本全文处理，长度: {} 字符", content.length());
                
                result.setCnSummary("原文全文");
                result.setCnContent(content);
                result.setCnSentences(performBasicSegmentation(content, "cn"));
                
                log.info("开始翻译中文到英文...");
                String enTranslation = translateInChunks(content, "cn", "en");
                result.setEnSummary("Full text translation");
                result.setEnContent(enTranslation);
                result.setEnSentences(performBasicSegmentation(enTranslation, "en"));
                
            } else {
                // 英文为源语言
                log.info("英文源文本全文处理，长度: {} 字符", content.length());
                
                result.setEnSummary("Original full text");
                result.setEnContent(content);
                result.setEnSentences(performBasicSegmentation(content, "en"));
                
                log.info("开始翻译英文到中文...");
                String cnTranslation = translateInChunks(content, "en", "cn");
                result.setCnSummary("原文全文翻译");
                result.setCnContent(cnTranslation);
                result.setCnSentences(performBasicSegmentation(cnTranslation, "cn"));
            }
            
            return result;
            
        } catch (Exception e) {
            log.error("全文模式处理失败", e);
            // 降级：使用原文内容，不翻译
            if ("cn".equals(sourceLang) || "zh".equals(sourceLang)) {
                result.setCnSummary("处理失败");
                result.setCnContent(content);
                result.setCnSentences(performBasicSegmentation(content, "cn"));
                result.setEnSummary("Processing failed");
                result.setEnContent("Translation failed");
                result.setEnSentences(performBasicSegmentation("Translation failed", "en"));
            } else {
                result.setEnSummary("Processing failed");
                result.setEnContent(content);
                result.setEnSentences(performBasicSegmentation(content, "en"));
                result.setCnSummary("处理失败");
                result.setCnContent("翻译失败");
                result.setCnSentences(performBasicSegmentation("翻译失败", "cn"));
            }
            return result;
        }
    }

    /**
     * 分段翻译（避免长文本超时）
     */
    private String translateInChunks(String content, String fromLang, String toLang) {
        final int CHUNK_SIZE = 2000;
        
        if (content.length() <= CHUNK_SIZE) {
            log.info("内容较短({} 字符)，一次性翻译", content.length());
            return translate(content, fromLang, toLang);
        }
        
        log.info("内容较长({} 字符)，分段翻译", content.length());
        
        try {
            java.util.List<String> chunks = splitByParagraphs(content, CHUNK_SIZE);
            log.info("已切分为 {} 段", chunks.size());
            
            StringBuilder result = new StringBuilder();
            
            for (int i = 0; i < chunks.size(); i++) {
                String chunk = chunks.get(i);
                log.info("翻译第 {}/{} 段", i + 1, chunks.size());
                
                String translated = translate(chunk, fromLang, toLang);
                result.append(translated);
                
                if (i < chunks.size() - 1) {
                    result.append("\n\n");
                    
                    // 延迟避免速率限制
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
            
            return result.toString().trim();
            
        } catch (Exception e) {
            log.error("分段翻译失败", e);
            return translate(content, fromLang, toLang);
        }
    }

    /**
     * 按段落边界切分文本
     */
    private java.util.List<String> splitByParagraphs(String content, int maxChunkSize) {
        java.util.List<String> chunks = new java.util.ArrayList<>();
        
        String[] paragraphs = content.split("\n\n|\n");
        StringBuilder currentChunk = new StringBuilder();
        
        for (String para : paragraphs) {
            para = para.trim();
            if (para.isEmpty()) {
                continue;
            }
            
            if (currentChunk.length() > 0 && 
                currentChunk.length() + para.length() + 2 > maxChunkSize) {
                chunks.add(currentChunk.toString().trim());
                currentChunk = new StringBuilder();
            }
            
            if (para.length() > maxChunkSize) {
                if (currentChunk.length() > 0) {
                    chunks.add(currentChunk.toString().trim());
                    currentChunk = new StringBuilder();
                }
                
                String[] sentences = para.split("(?<=[。！？.!?])");
                for (String sentence : sentences) {
                    if (currentChunk.length() + sentence.length() > maxChunkSize && currentChunk.length() > 0) {
                        chunks.add(currentChunk.toString().trim());
                        currentChunk = new StringBuilder();
                    }
                    currentChunk.append(sentence);
                }
            } else {
                if (currentChunk.length() > 0) {
                    currentChunk.append("\n\n");
                }
                currentChunk.append(para);
            }
        }
        
        if (currentChunk.length() > 0) {
            chunks.add(currentChunk.toString().trim());
        }
        
        if (chunks.isEmpty()) {
            chunks.add(content);
        }
        
        return chunks;
    }

    /**
     * 基础断句（不使用AI）
     */
    private String performBasicSegmentation(String content, String language) {
        com.alibaba.fastjson2.JSONArray sentences = new com.alibaba.fastjson2.JSONArray();

        String[] parts;
        if ("en".equals(language)) {
            parts = content.split("(?<=[.!?])\\s+");
        } else {
            parts = content.split("(?<=[。！？])");
        }

        int index = 0;
        for (String part : parts) {
            if (part.trim().isEmpty()) continue;

            com.alibaba.fastjson2.JSONObject sentence = new com.alibaba.fastjson2.JSONObject();
            sentence.put("index", index++);
            sentence.put("text", part.trim());
            sentences.add(sentence);
        }

        log.info("基础断句完成，共{}句", sentences.size());
        return sentences.toJSONString();
    }

    /**
     * 降级方案：使用原有方法逐个调用
     */
    private BilingualSummary generateBilingualSummaryFallback(String content, String sourceLang) {
        log.info("使用降级方案生成双语摘要");

        BilingualSummary result = new BilingualSummary();

        try {
            if ("cn".equals(sourceLang) || "zh".equals(sourceLang)) {
                String cnSummary = generateSummary(content, "cn");
                result.setCnSummary(cnSummary);

                String cnContent = content.length() > 300 ? content.substring(0, 300) + "..." : content;
                result.setCnContent(cnContent);
                result.setCnSentences(smartSegmentation(cnContent, "cn"));

                String enSummary = translate(cnSummary, "cn", "en");
                result.setEnSummary(enSummary);

                String enContent = translate(cnContent, "cn", "en");
                result.setEnContent(enContent);
                result.setEnSentences(smartSegmentation(enContent, "en"));

            } else {
                String enSummary = generateSummary(content, "en");
                result.setEnSummary(enSummary);

                String enContent = content.length() > 300 ? content.substring(0, 300) + "..." : content;
                result.setEnContent(enContent);
                result.setEnSentences(smartSegmentation(enContent, "en"));

                String cnSummary = translate(enSummary, "en", "cn");
                result.setCnSummary(cnSummary);

                String cnContent = translate(enContent, "en", "cn");
                result.setCnContent(cnContent);
                result.setCnSentences(smartSegmentation(cnContent, "cn"));
            }
        } catch (Exception e) {
            log.error("降级方案也失败了", e);
            String fallbackContent = content.length() > 300 ? content.substring(0, 300) : content;
            result.setCnSummary("AI处理失败");
            result.setCnContent(fallbackContent);
            result.setCnSentences(performBasicSegmentation(fallbackContent, "cn"));
            result.setEnSummary("AI processing failed");
            result.setEnContent(fallbackContent);
            result.setEnSentences(performBasicSegmentation(fallbackContent, "en"));
        }

        return result;
    }

    // Setters for configuration
    public void setApiKey(String apiKey) {
        this.apiKey = apiKey;
    }

    public void setApiEndpoint(String apiEndpoint) {
        this.apiEndpoint = apiEndpoint;
    }

    public void setModel(String model) {
        this.model = model;
    }
}

